<?php

namespace Portal\Api;

use Portal\Common\DataApi as Api;
use PhalApi\Exception\BadRequestException;

// use PhalApi\Api;

/**
 *字典项接口
 * @author chenwengen 20240420
 */
class DictItem extends Api
{
    public function getRules()
    {
        return array(
            'tableList' => array(
                'dict_code' => array('name' => 'dictCode', 'type' => 'string', "require" => true, 'desc' => '字典编码'),
                 'page' => array('name' => 'pageNum', 'type' => 'int', 'default' => 1, 'min' => 1, 'desc' => '页码'),
                'limit' => array('name' => 'pageSize', 'type' => 'int', 'default' => 10, 'min' => 1, 'max' => 100, 'desc' => '每页记录数'),
                'keywords' => array('name' => 'keywords', 'type' => 'string','require' => false, 'desc' => '关键字(字典类型名称/编码)'),
            ),
            'createData' => array(
                'dict_code' => array('name' => 'dictCode', 'type' => 'string', 'require' => true,'desc' => '字典编码'),
                 'label' => array('name' => 'label', 'type' => 'string', 'require' => true,'desc' => '字典项标签'),
                 'value' => array('name' => 'value', 'type' => 'string', 'require' => true,'desc' => '字典项值'),
                 'sort' => array('name' => 'sort', 'type' => 'int', 'require' => true,'min' => 0,'desc' => 'sort'),
                 'status' => array('name' => 'status', 'type' => 'enum', 'require' => false,'range' => array('0', '1'),'desc' => '类型状态(1:启用;0:禁用)'),
                 'tag_type' => array('name' => 'tagType', 'require' => false, 'type' => 'enum', 'range' => array('','primary', 'success','info','warning','danger'),'desc' => '用于显示样式'),
              ),
            'deleteData' => array(
                'ids' => array('name' => 'id', 'type' => 'array', 'format' => 'explode', 'seperator' => ',', 'require' => true, 'desc' => \PhalApi\T('ids to delete')),
            ),
            'deleteDataIDs' => array(
                'dict_code' => array('name' => 'dictCode', 'type' => 'string', 'require' => true,'desc' => '字典编码'),
                'ids' => array('name' => 'ids', 'type' => 'array', 'format' => 'explode', 'seperator' => ',', 'require' => true, 'desc' => \PhalApi\T('ids to delete'))
            ),
            'updateData' => array(
                'id' => array('name' => 'id', 'type' => 'int', 'require' => true, 'min' => 1, 'desc' => 'ID'),
                 'dict_code' => array('name' => 'dictCode', 'type' => 'string', 'require' => true,'desc' => '字典编码'),
                 'label' => array('name' => 'label', 'type' => 'string', 'require' => true,'desc' => '字典项标签'),
                 'value' => array('name' => 'value', 'type' => 'string', 'require' => true,'desc' => '字典项值'),
                 'sort' => array('name' => 'sort', 'type' => 'int', 'require' => true,'min' => 0,'desc' => 'sort'),
                 'status' => array('name' => 'status', 'type' => 'enum', 'require' => false,'range' => array('0', '1'),'desc' => '类型状态(1:启用;0:禁用)'),
                 'tag_type' => array('name' => 'tagType', 'require' => false, 'type' => 'enum', 'range' => array('','primary', 'success','info','warning','danger'),'desc' => '用于显示样式'),            ),
           'getData' => array(
                'id' => array('name' => 'id', 'type' => 'int', 'require' => true, 'min' => 1, 'desc' => 'ID'),
            ),
            'items' => array(
                'dict_code' => array('name' => 'dictCode',  'require' => true, 'desc' => "字典编码"),
            ),
        );
    }
    protected function getDataModel()
    {
        return  new \Portal\Model\DictItem();
    }
    /**
     * 字典项列表
     * @desc 字典项列表
     */
    public function items()
    {
        $dictCode = $this->dict_code;
        $datas = $this->getDataModel()::notorm()->select('label,value,tag_type AS tagType')->where(['dict_code' => $dictCode,'status' => 1])->order('sort')->fetchAll();
        foreach ($datas as $data) {
            $returnData[] = $data;
        }
        return $returnData;
    }
    /**
     * 获取表格列表数据
     * @desc 通用数据接口，获取表格列表数据，默认按ID降序返回，支持分页和搜索
     */
    public function tableList()
    {
        $this->permissionRequired(["sys:dict-item:query"]);
        $model = $this->getDataModel();

        $searchParams = array();
        // foreach ($this->searchParams as $key => $val) {
        //     if ($val !==  '') {
        //         $searchParams[$key] = $val;
        //     }
        // }
        $searchParams['dict_code'] = $this->dict_code;
        // 条件
        $where = !empty($searchParams) ? $searchParams : null;
        $whereParams = array();
        $where = $this->getTableListWhere($where);

        $select = $this->getTableListSelect();
        $order = $this->getTableListOrder();
        $page = $this->page;
        $perpage = $this->limit;

        $total = $model->count($where);
        $items = $total > 0 ? $model->getList($where, $whereParams, $select, $order, $page, $perpage) : array();
        $items = $this->afterTableList($items);

        // return $this->returnDataResult(array('total' => $total, 'items' => $items));
        return $this->returnDataResult(array('total' => $total, 'list' => $items));
    }

    // 列表返回的字段
    protected function getTableListSelect()
    {
        return 'id,label,dict_code AS dictCode,value,sort,status';
    }

    // 列表的默认排序
    protected function getTableListOrder()
    {
        return 'sort';
    }

    // 查询条件
    protected function getTableListWhere($where)
    {
        if ($this->keywords !== null && trim($this->keywords) != '') {
            // $where['dict_code LIKE ? OR label LIKE ?'] = array("%$this->keywords%","%$this->keywords%");
            $where['(label LIKE ? OR value LIKE ?)'] = array("%$this->keywords%","%$this->keywords%");
        }
        $viewableUsers = $this->dataPermissionRequired("select");
        if ($viewableUsers != "all" && is_array($viewableUsers) && !empty($viewableUsers)) {
            $where['create_by'] = $viewableUsers;
        }
        return $where;
    }

    // 取到列表数据后的加工处理
    protected function afterTableList($items)
    {
        foreach ($items as $key => $item) {
            if (isset($item['id'])) {
                $item['id'] = strval($item['id']);
            }

            $items[$key] = $item;
        }
        return $items;
    }
    /**
      * 创建新数据
      * @desc 通用数据接口，创建一条新数据
      * @return int id 新纪录的ID
      */
    public function createData()
    {
        $this->permissionRequired(["sys:dict-item:add"]);
        //检查字典是否存在
        $checkDictData = \Portal\Model\Dict::notorm()->select('id,create_by')->where(['dict_code' => $this->dict_code,'is_deleted' => 0])->fetchOne();
        if (!$checkDictData) {
            throw new BadRequestException("字典编码".$this->dict_code."不存在", 3);
        }
        # 检查用户对该字典的操作权限
        $dataPermission = $this->dataPermissionRequired("add", $checkDictData['create_by']);
        if (!$dataPermission) {
            throw new BadRequestException("无权限向此字典添加项", 3);
        }

        $model = $this->getDataModel();
        // $newData = $this->newData;
        $array_keys = array_keys($this->getApiRules());
        $newData = [];
        foreach ($array_keys as $key) {
            if ($this->$key !== null) {
                $newData[$key] = $this->$key;
            }
        }
        // 检测必传字段
        foreach ($this->createDataRequireKeys() as $key) {
            if (!isset($newData[$key]) || $newData[$key] === '') {
                throw new BadRequestException(\PhalApi\T('{name} require, but miss', array('name' => $key)));
            }
        }
        // 排除字段
        foreach ($this->createDataExcludeKeys() as $key) {
            unset($newData[$key]);
        }

        // 更多初始化的字段数据
        $newData = $this->beforeCreateData($newData);

        if (empty($newData)) {
            throw new BadRequestException(\PhalApi\T('miss post data'));
        }

        $id = 0;
        try {
            $id = $model->insert($newData);
        } catch (\PDOException $ex) {
            throw new BadRequestException(\PhalApi\DI()->debug ? $ex->getMessage() : \PhalApi\T('system error, please contact engeneer'));
        }

        return $this->returnDataResult(array('id' => intval($id)));
    }
    private function validateDictCode($dictCode)
    {
        //"验证字典编码是否存在
        $checkData = \Portal\Model\Dict::notorm()->select('id')->where(['dict_code' => $dictCode,'is_deleted' => 0,])->fetchOne();
        if (!$checkData) {
            throw new BadRequestException("字典编码".$dictCode."不存在", 3);
        }
    }
    private function validateDictCodeValue($dictCode, $value)
    {
        //"验证字典编码是否存在
        $checkData = $this->getDataModel()::notorm()->select('id')->where(['dict_code' => $dictCode,'value' => $value,])->fetchOne();
        if ($checkData) {
            throw new BadRequestException("字典项值".$value." 在字典".$dictCode."中已存在", 3);
        }
    }

    // 必须提供的字段
    protected function createDataRequireKeys()
    {
        return array('label','value');
    }

    // 不允许客户端写入的字段
    protected function createDataExcludeKeys()
    {
        return array('create_time','update_time','create_by','update_by');
    }

    // 创建时更多初始化的数据
    protected function beforeCreateData($newData)
    {
        $this-> validateDictCodeValue($newData['dict_code'], $newData['value']);
        $time = time();
        $newData['create_time'] = $time;
        $newData['update_time'] = $time;
        $newData['create_by'] = \PhalApi\DI()->admin->getId();
        return $newData;
    }

    /**
     * 根据ID删除数据
     * @desc 根据单个ID删除数据，也可以调整成根据自定义的条件删除数据
     */
    public function deleteData()
    {
        // $where = array('id' => $this->ids);
        // $model = $this->getDataModel();
        // // $rows = !empty($where) ? $model->deleteAll($where) : 0;
        // $this->delDict();
        // $rows = $model->updateAll(['id' => $this->ids], ['deleted' => 1]) ?: 0;

        // return $this->returnDataResult(array('deleted_num' => $rows));
        $this->ids = [$this->id];
        $this->deleteDataIDs();
    }

    // 删除数据的条件加工
    protected function getDeleteDataWhere($where)
    {
        return $where;
    }

    /**
     * 批量删除
     * @desc 通用数据接口，根据ID批量删除数据
     */
    public function deleteDataIDs()
    {
        $this->permissionRequired(["sys:dict-item:delete"]);
        $model = $this->getDataModel();
        #检查字典是否存在
        $this->validateDictCode($this->dict_code);
        # 查询要删除的字典项
        $itemsToDelete = $model::notorm()->select('id,label,create_by')->where(['id' => $this->ids,'dict_code' => $this->dict_code])->fetchPairs('id');

        if (count($itemsToDelete) != count($this->ids)) {
            $missingIds = [];
            foreach ($this->ids as $id) {
                if (!isset($itemsToDelete[$id])) {
                    $missingIds[] = $id;
                }
            }
            throw new BadRequestException("未找到ID为".implode(',', $missingIds)."的字典项", 3);
        }
        # 检查每个字典项的权限
        $unauthorizedItems = [];
        foreach ($itemsToDelete as $itemToDelete) {
            $dataPermission = $this->dataPermissionRequired("delete", $itemToDelete['create_by']);
            if (!$dataPermission) {
                $unauthorizedItems[] = $itemToDelete['label'].'ID:'.$itemToDelete['id'];
            }
        }
        if (!empty($unauthorizedItems)) {
            throw new BadRequestException("无权限删除以下字典项：".implode(',', $unauthorizedItems), 3);
        }
        $rows = $this->ids ? $model->deleteIds($this->ids) : 0;

        return $this->returnDataResult(array('deleted_num' => $rows));
    }


    /**
     * 获取一条数据
     * @desc 通用数据接口，根据ID获取一条数据
     * @return object
     * @exception 403 信息不存在
     */
    public function getData()
    {
        $this->permissionRequired(["sys:dict-item:query"]);
        $where = array('id' => $this->id);
        $whereParams = array();
        $select = $this->getDataSelect();

        // 前置条件加工
        $where = $this->getGetDataWhere($where);

        $model = $this->getDataModel();
        $checkData = $model::notorm()->select('id,create_by')->where(['id' => $this->id])->fetchOne();
        if (!$checkData) {
            throw new BadRequestException("信息不存在", 3);
        }
        $dataPermission = $this->dataPermissionRequired("select", $checkData['create_by']);
        if (!$dataPermission) {
            throw new BadRequestException("无权限查看此字典项", 3);
        }
        $data = $model->getData($where, $whereParams, $select);

        $data = $this->afterGetData($data);

        // return $this->returnDataResult(array('data' => $data ? $data : null));
        return $this->returnDataResult($data);
    }

    // 获取单个数据时需要返回的字段
    protected function getDataSelect()
    {
        return 'id,dict_code AS dictCode,label,value,status,tag_type AS tagType,sort';
    }

    // 前置条件加工
    protected function getGetDataWhere($where)
    {
        return $where;
    }

    // 取到数据后的加工处理
    protected function afterGetData($data)
    {
        if (isset($data['id'])) {
            $data['id'] = strval($data['id']);
        }
        return $data;
    }

    /**
     * 更新数据
     * @desc 通用数据接口，根据ID更新单条数据
     * @return int|boolean updated_num 更新的数据条数，0表示无更新，1表示更新成功
     */
    public function updateData()
    {
        $this->permissionRequired(["sys:dict-item:edit"]);
        $model = $this->getDataModel();
        // $updateData = $this->data;
        $array_keys = array_keys($this->getApiRules());
        $updateData = [];
        foreach ($array_keys as $key) {
            if ($this->$key !== null && $key !== 'data') {
                $updateData[$key] = $this->$key;
            }
        }
        unset($updateData['id']);
        //检查字典是否存在
        //检查字典是否存在
        $checkDictData = \Portal\Model\Dict::notorm()->select('id,create_by')->where(['dict_code' => $this->dict_code,'is_deleted' => 0])->fetchOne();
        if (!$checkDictData) {
            throw new BadRequestException("字典编码".$this->dict_code."不存在", 4);
        }

        # 检查用户对该字典的操作权限
        $dataPermission = $this->dataPermissionRequired("update", $checkDictData['create_by']);
        if (!$dataPermission) {
            throw new BadRequestException("无权限向此字典添加项", 3);
        }
        $getDictItemData = $this->getDataModel()::notorm()->select('id,value')->where(['dict_code' => $this->dict_code,'id' => $this->id])->fetchOne();
        if ($getDictItemData['value'] != $this->value) {
            //验证value唯一性
            $this->validateDictCodeValue($this->dict_code, $this->value);
        }
        foreach ($this->updateDataRequireKeys() as $key) {
            if (!isset($updateData[$key]) || $updateData[$key] === '') {
                throw new BadRequestException(\PhalApi\T('{name} require, but miss', array('name' => $key)));
            }
        }

        foreach ($this->updateDataExcludeKeys() as $key) {
            unset($updateData[$key]);
        }

        if (empty($updateData)) {
            throw new BadRequestException(\PhalApi\T('miss update data'));
        }

        $updateData = $this->beforeUpdateData($updateData);

        try {
            $where = array('id' => $this->id);
            $where = $this->getUpdateDataWhere($where);

            $rows = $model->updateAll($where, $updateData);
            return $this->returnDataResult(array('updated_num' => $rows));
        } catch (\PDOException $ex) {
            throw new BadRequestException(\PhalApi\DI()->debug ? $ex->getMessage() : \PhalApi\T('system error, please contact engeneer'));
        }
    }

    // 更新时必须提供的字段
    protected function updateDataRequireKeys()
    {
        return array('label','value','dict_code');
    }

    // 更新时不允许更新的字段
    protected function updateDataExcludeKeys()
    {
        return array('create_time','update_time','create_by','update_by');
    }

    // 获取更新数据的条件
    protected function getUpdateDataWhere($where)
    {
        return $where;
    }

    // 在更新数据前的处理
    protected function beforeUpdateData($updateData)
    {
        $time = time();
        $updateData['update_time'] = $time;
        $updateData['update_by'] = \PhalApi\DI()->admin->getId();
        return $updateData;
    }
}
